package app.models.order;

import app.kit.TypeKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;
import goja.StringPool;
import goja.annotation.TableBind;
import goja.plugins.sqlinxml.SqlKit;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.util.List;

import static app.Const.FIELD_AMOUNT;
import static app.Const.FIELD_MEMBER;
import static app.Const.FIELD_ORDER_ID;
import static app.Const.FIELD_PRODUCT;
import static app.Const.FIELD_STATUS;
import static app.Const.FIELD_TYPE;

/**
 * <p>
 * The database rlo_trade_money Model.
 * </p>
 *
 * @author sagyf yang
 * @version 1.0
 * @since JDK 1.6
 */
@TableBind(tableName = "rlo_trade_money")
public class TradeMoney extends Model<TradeMoney> {

    /**
     * The public dao.
     */
    public static final TradeMoney dao = new TradeMoney();


    private static final long serialVersionUID = -5590051492035157673L;


    /**
     * 待打款
     */
    public static final int WAIT_STATUS    = 0;
    /**
     * 财务确认打款
     */
    public static final int CONFIRM_STATUS = 1;
    /**
     * 领导审核确认打款
     */
    public static final int OK_STATUS      = 2;
    /**
     * 已打款
     */
    public static final int SUCCESS_STATUS = 3;
    /**
     * 打款失败
     */
    public static final int FAIL_STATUS    = 4;

    /**
     * 每日收益打款
     */
    public static final int DAILY_TYPE          = 1;
    /**
     * 每月收益打款
     */
    public static final int MONTH_TYPE          = 2;
    /**
     * 产品到期收益打款
     */
    public static final int DUE_TYPE            = 3;
    /**
     * 转让打款
     */
    public static final int TRANSFER_TYPE       = 4;
    /**
     * 产品撤单打款
     */
    public static final int CANCEL_TYPE         = 5;
    /**
     * 募集失败打款
     */
    public static final int FAIL_TYPE           = 6;
    /**
     * 募集成功提现
     */
    public static final int RAISED_SUCCESS_TYPE = 7;
    /**
     * 支付失败打款单
     */
    public static final int PAY_FAIL_TYPE = 8;


    /**
     * 支付失败打款单
     *
     * @param product         产品
     * @param amount       支付金额
     * @return 操作成功
     */
    public static TradeMoney payFail(int product, BigDecimal amount,String memberCode,int member, Order order) {
        final TradeMoney tradeMoney = new TradeMoney();
        tradeMoney.set(FIELD_MEMBER, member);
        tradeMoney.set(FIELD_ORDER_ID, TypeKit.getInt(order, StringPool.PK_COLUMN));
        tradeMoney.set("member_code", memberCode);
        tradeMoney.set("member_product", 0);
        tradeMoney.set(FIELD_PRODUCT, product);
        tradeMoney.set(FIELD_AMOUNT, amount);
        final DateTime now = DateTime.now();
        tradeMoney.set("submit_time", now);
        tradeMoney.set("submit_time_year", now.getYear());
        tradeMoney.set("submit_time_month", now.getMonthOfYear());
        tradeMoney.set("submit_time_day", now.getDayOfMonth());
        tradeMoney.set(FIELD_STATUS, WAIT_STATUS);
        tradeMoney.set(FIELD_TYPE, TradeMoney.PAY_FAIL_TYPE);
        return tradeMoney;
    }
    /**
     * 产品募集成功提现打款
     *
     * @param product         产品
     * @param amount       投资金额
     * @return 操作成功
     */
    public static TradeMoney raisedSuccess(int product, BigDecimal amount) {
        final TradeMoney tradeMoney = new TradeMoney();
        tradeMoney.set(FIELD_MEMBER, 0);
        tradeMoney.set("member_code", StringPool.EMPTY);
        tradeMoney.set("member_product", 0);
        tradeMoney.set(FIELD_PRODUCT, product);
        tradeMoney.set(FIELD_AMOUNT, amount);
        final DateTime now = DateTime.now();
        tradeMoney.set("submit_time", now);
        tradeMoney.set("submit_time_year", now.getYear());
        tradeMoney.set("submit_time_month", now.getMonthOfYear());
        tradeMoney.set("submit_time_day", now.getDayOfMonth());
        tradeMoney.set(FIELD_STATUS, WAIT_STATUS);
        tradeMoney.set(FIELD_TYPE, TradeMoney.RAISED_SUCCESS_TYPE);
        return tradeMoney;
    }

    /**
     * 创建到期收益预打款纪录
     *
     * @param member          会员
     * @param memberCode      会员编号
     * @param product         产品
     * @param memberProductId 会员产品
     * @param principal       本金
     * @param profit          收益
     * @return 操作成功
     */
    public static TradeMoney dueProfitMoney(int member, String memberCode,
                                            int product, int memberProductId,
                                            BigDecimal principal, BigDecimal profit) {
        TradeMoney tradeMoney = createTradeMoney(member, memberCode, product, memberProductId, principal, profit);
        tradeMoney.set(FIELD_TYPE, TradeMoney.DUE_TYPE);
        return tradeMoney;
    }

    /**
     * 创建退单打款纪录
     *
     * @param member        会员
     * @param memberCode    会员编号
     * @param product       产品
     * @param amount        金额（购买金额)
     * @param memberProduct 会员产品ID
     * @return 操作成功
     */
    public static TradeMoney createCancelPlayMoney(int member, String memberCode, int product, BigDecimal amount, int memberProduct) {
        final TradeMoney tradeMoney = new TradeMoney();
        tradeMoney.set(FIELD_MEMBER, member);
        tradeMoney.set("member_code", memberCode);
        tradeMoney.set("member_product", memberProduct);
        tradeMoney.set(FIELD_PRODUCT, product);
        tradeMoney.set(FIELD_AMOUNT, amount);
        final DateTime now = DateTime.now();
        tradeMoney.set("submit_time", now);
        tradeMoney.set("submit_time_year", now.getYear());
        tradeMoney.set("submit_time_month", now.getMonthOfYear());
        tradeMoney.set("submit_time_day", now.getDayOfMonth());
        tradeMoney.set(FIELD_STATUS, WAIT_STATUS);
        tradeMoney.set(FIELD_TYPE, TradeMoney.CANCEL_TYPE);
        return tradeMoney;
    }

    /**
     * 创建每月收益预打款纪录
     *
     * @param member          会员
     * @param memberCode      会员编号
     * @param product         产品
     * @param memberProductId 会员产品
     * @param principal       本金
     * @param profit          收益
     * @return 操作成功
     */
    public static TradeMoney monthProfitMoney(int member, String memberCode, int product, int memberProductId, BigDecimal principal, BigDecimal profit) {
        TradeMoney tradeMoney = createTradeMoney(member, memberCode, product, memberProductId, principal, profit);
        tradeMoney.set(FIELD_TYPE, TradeMoney.MONTH_TYPE);
        return tradeMoney;
    }

    /**
     * 写入收益预打款纪录
     *
     * @param member          会员
     * @param memberCode      会员编号
     * @param product         产品
     * @param memberProductId 会员产品
     * @param principal       本金
     * @param profit          收益
     * @return 操作成功
     */
    private static TradeMoney createTradeMoney(int member, String memberCode, int product, int memberProductId, BigDecimal principal, BigDecimal profit) {
        TradeMoney tradeMoney = new TradeMoney();
        tradeMoney.set(FIELD_MEMBER, member);
        tradeMoney.set("member_code", memberCode);
        tradeMoney.set(FIELD_PRODUCT, product);
        tradeMoney.set(FIELD_AMOUNT, principal.add(profit));
        tradeMoney.set("member_product", memberProductId);
        tradeMoney.set("profit", profit);
        tradeMoney.set("principal", principal);
        final DateTime now = DateTime.now();
        tradeMoney.set("submit_time", now);
        tradeMoney.set("submit_time_year", now.getYear());
        tradeMoney.set("submit_time_month", now.getMonthOfYear());
        tradeMoney.set("submit_time_day", now.getDayOfMonth());
        tradeMoney.set(FIELD_STATUS, WAIT_STATUS);
        return tradeMoney;
    }


    public TradeMoney findByUpdate(int id) {
        return findFirst(SqlKit.sql("trademoney.findByUpdate"), id);
    }

    public List<TradeMoney> findByStatus(int status) {
        return find(SqlKit.sql("trademoney.findByStatus"), status, DUE_TYPE, MONTH_TYPE, DAILY_TYPE, FAIL_TYPE);
    }


    public List<TradeMoney> findByIds(String data, int type) {
        return find(String.format(SqlKit.sql("trademoney.findByIdarray"), data), type);
    }

    public BigDecimal countAmount(String ids) {
        TradeMoney count = findFirst(String.format(SqlKit.sql("trademoney.countAmount"), ids));
        if(count == null){
            return BigDecimal.ZERO;
        } else {
            return count.getBigDecimal("amount");
        }
    }

    public TradeMoney findDetailById(String trade_money_id) {
        return findFirst(SqlKit.sql("trademoney.findDetailById"), trade_money_id);
    }

    public BigDecimal sumProfit() {
        TradeMoney tr = findFirst(SqlKit.sql("trademoney.sumProfit"), DUE_TYPE, SUCCESS_STATUS);
        return TypeKit.getBigdecimal(tr, "amount");
    }

    public Record statFailByDay(String day) {
        return Db.findFirst(SqlKit.sql("clearing.payfail.stat"),PAY_FAIL_TYPE, day);
    }



    public void setTime(DateTime resp_date) {
        final int year = resp_date.getYear();
        final int monthOfYear = resp_date.getMonthOfYear();
        final int dayOfMonth = resp_date.getDayOfMonth();
        this.set("money_time", resp_date);
        this.set("money_time_year", year);
        this.set("money_time_month", monthOfYear);
        this.set("money_time_day", dayOfMonth);
        this.set("submit_time", resp_date);
        this.set("submit_time_year", year);
        this.set("submit_time_month", monthOfYear);
        this.set("submit_time_day", dayOfMonth);
    }


    public BigDecimal adjustAmount(){
        // 打款金额
        BigDecimal amount = this.getBigDecimal(FIELD_AMOUNT);
        // 调整方式
        int adjust_mode = TypeKit.getInt(this, "adjust_mode");
        if (adjust_mode > 0) {
            BigDecimal adjust_amount = TypeKit.getBigdecimal(this, "adjust_amount");
            if (adjust_mode == 1) {
                // 增加
                amount = amount.add(adjust_amount);
            } else if (adjust_mode == 2) {
                // 减少
                amount = amount.subtract(adjust_amount);
            }
        }
        return amount.setScale(2, BigDecimal.ROUND_HALF_UP);
    }
}